package com.semidata.trp.decision.business;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.semidata.rtd.core.iplib.Area;
import com.semidata.rtd.core.json.JsonObject;
import com.semidata.rtd.core.log.Logger;
import com.semidata.trp.message.business.Business;
import com.semidata.trp.message.business.Business.Strategy.MaterialWeight;

public class Strategy {

	private int id;
	private Resource resource;
	private double price;
	private int orgId;
	private int priority;
	private int frequency;
	private int algoId;
	private double totalBudgetIn;
	private double dailyBudgetIn;
	private double totalBudgetOut;
	private double dailyBudgetOut;
	private double totalBudgetAlly;
	private double dailyBudgetAlly;
	private JsonObject algoParams;
	private Set<Area> areas;
	private Set<Integer> hours;
	private String landingPage;
	private Map<Material, Integer> materialWeights;
	private List<Business.KeyWord> keywords;

	public String toString() {
		StringBuffer sb = new StringBuffer();

		sb.append("Strategy ").append(id).append(" [").append(price)
				.append(", ").append(orgId).append(", ");
		sb.append(priority).append(", ").append(frequency).append(", [");
		for (Area area : areas) {
			sb.append(area.toString()).append(", ");
		}
		sb.append("], [");
		for (int hour : hours) {
			sb.append(hour).append(", ");
		}
		sb.append("], ").append(landingPage).append("]\n");
		for (Material material : materialWeights.keySet()) {
			sb.append(material.toString());
		}
		sb.append('\n');
		return sb.toString();
	}

	public Strategy(Business.Strategy data, Resource resource, double price,
			Map<Integer, Material> materials) {
		this.id = data.getId();
		this.resource = resource;
		this.price = price;
		this.orgId = data.getOrgId();
		this.algoId = data.getAlgorithmId();
		this.priority = data.getPriority();
		this.frequency = data.getFrequency();
		this.keywords = data.getKeywordsList();
		this.totalBudgetIn = data.getTotalBudgetIn();
		this.dailyBudgetIn = data.getDailyBudgetIn();
		this.totalBudgetOut = data.getTotalBudgetOut();
		this.dailyBudgetOut = data.getDailyBudgetOut();
		this.totalBudgetAlly = data.getTotalBudgetAlly();
		this.dailyBudgetAlly = data.getDailyBudgetAlly();

		if (data.getParams() != null && data.getParams().length() > 0) {
			this.algoParams = new JsonObject(data.getParams());
		}
		// System.out.println("print keyworkds");
		// if (keywords != null) {
		// for (Business.KeyWord kw : this.keywords) {
		//
		// System.out.println(kw.getKeyword1() + "-" + kw.getKeyword2() + "-" +
		// kw.getKeyword3());
		// }
		// }
		areas = new HashSet<>();
		for (String area : data.getAreasList()) {
			areas.add(new Area(area));
		}

		hours = new HashSet<>();
		for (int hour : data.getHoursList()) {
			hours.add(hour);
		}

		this.landingPage = data.getLandingPage();
		if (this.landingPage == null || this.landingPage.isEmpty())
			this.landingPage = null;

		materialWeights = new HashMap<>();

		for (MaterialWeight item : data.getMaterialWeightsList()) {

			Material material = materials.get(item.getMaterialId());
			if (material == null || item.getWeight() <= 0) {
				Logger.log(
						"DEBUG",
						material == null ? "material is null" : ("material "
								+ item.getMaterialId() + " weight is " + item
								.getWeight()));
				continue;
			}

			Position position = resource.getPosition();

			if (position.getId() == 197) {
				Logger.log("DEBUG", "handle position 197");
			}

			if (position.getWidth() != material.getWidth()
					|| position.getHeight() != material.getHeight()
					|| position.getSize() < material.getSize()
					|| !position.getTypes().contains(material.getType())) {

				if (position.getId() == 197) {
					if (position.getWidth() != material.getWidth()) {
						Logger.log(
								"DEBUG",
								"Width is not match. material "
										+ material.getId() + " width = "
										+ material.getWidth() + ", position "
										+ position.getId() + " width = "
										+ position.getWidth());
					}

					if (position.getHeight() != material.getHeight()) {
						Logger.log(
								"DEBUG",
								"Height is not match. material "
										+ material.getId() + " height = "
										+ material.getHeight() + ", position "
										+ position.getId() + " height = "
										+ position.getHeight());
					}

					if (position.getSize() < material.getSize()) {
						Logger.log(
								"DEBUG",
								"Size is not match. material "
										+ material.getId() + " size = "
										+ material.getSize() + ", position "
										+ position.getId() + " size = "
										+ position.getSize());
					}

					if (!position.getTypes().contains(material.getType())) {
						Logger.log(
								"DEBUG",
								"Type is not match. material "
										+ material.getId() + " type = "
										+ material.getType() + ", position "
										+ position.getId() + " type = "
										+ position.getTypes().toString());
					}
				}
				continue;
			}

			if (position.getId() == 197) {
				Logger.log("DEBUG", "there is material in position 197");
			}
			materialWeights.put(material, item.getWeight());
		}
	}

	public Strategy(Strategy s) {
		this.id = s.getId();
		this.resource = s.getResource();
		this.price = s.getPrice();
		this.orgId = s.getOrgId();
		this.priority = s.getPriority();
		this.frequency = s.getFrequency();
		this.areas = s.getAreas();
		this.hours = s.getHours();
		this.algoId = s.getAlgoId();
		this.algoParams = s.getAlgoParams();
		this.keywords = s.getKeywords();
		this.landingPage = s.getLandingPage();
		this.totalBudgetIn = s.getTotalBudgetIn();
		this.dailyBudgetIn = s.getDailyBudgetIn();
		this.totalBudgetOut = s.getTotalBudgetOut();
		this.dailyBudgetOut = s.getDailyBudgetOut();
		this.totalBudgetAlly = s.getTotalBudgetAlly();
		this.dailyBudgetAlly = s.getDailyBudgetAlly();
		if (this.landingPage == null || this.landingPage.isEmpty())
			this.landingPage = null;
		materialWeights = new HashMap<>();
		materialWeights.putAll(s.getMaterialWeights());

	}

	public int getId() {
		return id;
	}

	public JsonObject getAlgoParams() {
		return this.algoParams;
	}

	public int getAlgoId() {
		return algoId;
	}

	public Resource getResource() {
		return resource;
	}

	public double getPrice() {
		return price;
	}

	public int getOrgId() {
		return orgId;
	}

	public int getPriority() {
		return priority;
	}

	public int getFrequency() {
		return frequency;
	}

	public Set<Area> getAreas() {
		return areas;
	}

	public Set<Integer> getHours() {
		return hours;
	}

	public String getLandingPage() {
		return landingPage;
	}

	public Map<Material, Integer> getMaterialWeights() {
		return materialWeights;
	}

	public List<Business.KeyWord> getKeywords() {
		return keywords;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public double getTotalBudgetIn() {
		return totalBudgetIn;
	}

	public double getDailyBudgetIn() {
		return dailyBudgetIn;
	}

	public double getTotalBudgetOut() {
		return totalBudgetOut;
	}

	public double getDailyBudgetOut() {
		return dailyBudgetOut;
	}

	public double getTotalBudgetAlly() {
		return totalBudgetAlly;
	}

	public double getDailyBudgetAlly() {
		return dailyBudgetAlly;
	}

}
